<?php

namespace app\index\service;

use app\common\job\SmsLanding;
use app\common\model\Consulting;
use app\common\model\ConsultingMessage;
use app\common\model\ConsultingQuestion;
use app\common\model\ConsultingServer;
use app\common\model\ConsultingServerSku;
use app\common\model\Landing;
use app\common\model\Trade;
use app\common\service\ARYPushQueueService;
use app\common\traits\AreaTrait;
use app\index\dao\TradeDao;
use app\index\model\UM as UM;
use app\index\traits\TradeBroadcastTrait;
use app\index\traits\TradeShareEstimateTrait;
use think\exception\ValidateException;
use think\facade\Config;
use think\facade\Queue;

/**
 * 落地页订单
 * Class TradeLandingService
 * @package app\index\service
 */
class TradeLandingService implements TradableInterface
{
    use TradeShareEstimateTrait;
    use TradeBroadcastTrait;
    use AreaTrait;

    // dao
    private TradeDao $tradeDao;

    public function __construct(TradeDao $tradeDao)
    {
        $this->tradeDao = $tradeDao;
    }

    /**
     * 新增
     * @param UM $user
     * @param array $params
     * @return  \app\common\model\Trade
     */
    public function add(UM $user, array $params): Trade
    {
        // 补齐参数，创建Trade
        $tradeType = TRADE_LANDING;
        $tradeConfig = Config::get("trade.trades.$tradeType", []);
        $tradeTypeClass = $tradeConfig['className'] ?? '';

        $landingId = $params['landingId'] ?? '0';
        $serverId = $params['serverId'] ?? '0';
        $serverSkuId = $params['serverSkuId'] ?? '0';
        $pagePath = $params['pagePath'] ?? '';

        // 渠道链路
        ['pf' => $pf, 'chain' => $chain, 'promotionGroupId' => $promotionGroupId] = getChainParams();

        // 推广回传
        $promotionFeedback = $params['promotionFeedback'] ?? null;

        // 落地页信息
        $landing = Landing::where('id', $landingId)
                          ->with(['fromChain'])
                          ->find();
        if (!$landing) {
            throw new ValidateException('该案件不存在，或已被删除');
        }
        if ($landing->status != 0) {
            if ($landing->status == 1) {
                throw new ValidateException('该案件已支付成功');
            }
            if ($landing->status == 2) {
                throw new ValidateException('该案件已退款');
            }
            throw new ValidateException('案件状态错误');
        }

        // 保存路径
        $landing->pagePath = $pagePath;
        $landing->save();

        // 记录落地页类型
        $landingType = $landing->landingType;
        // 电话
        $phone = $landing->phone;

        $server = ConsultingServer::where('id', $serverId)->find();
        if (!$server) {
            throw new ValidateException('请选择一个咨询服务');
        }
        if ($server->serverType == ConsultingServer::FREE) {
            throw new ValidateException('请选择一个付费咨询服务');
        }

        $sku = null;
        if (is_id($serverSkuId)) {
            $sku = ConsultingServerSku::where('id', $serverSkuId)
                                      ->where('consultingServerId', $serverId)
                                      ->find();
            if (!$sku) {
                throw new ValidateException('该咨询服务不存在或已被删除');
            }
        }

        // 描述
        $describe = $tradeConfig['name'];
        if ($landing->fromChain) {
            $describe = $landing->fromChain->showName;
        }
        if ($sku) {
            $describe .= '-' . $sku->name;
        } else {
            $describe .= '-' . $server->name;
        }

        // 价格
        if ($sku) {
            $showMoney = $sku->showPrice;
            $totalMoney = $sku->price;
        } else {
            $showMoney = $server->showPrice;
            $totalMoney = $server->price;
        }
        $payMoney = $totalMoney;
        $settleStatus = Trade::UNSETTLED;

        $phones = array_merge(Config::get('member.developerAccount', []), Config::get('member.testAccount', []));
        if (in_array($user->phone, $phones)) {
            $payMoney = '0.01';
            $settleStatus = Trade::NOTSETTLE;
        }

        if ($payMoney < 0.01) {
            throw new ValidateException('订单价格应该大于0');
        }

        $tradeParams = [
            'memberId' => $user->id,
            'orderNoPre' => 'LD',
            'describe' => $describe,
            'tradeType' => $tradeType,
            'tradeTypeClass' => $tradeTypeClass,
            'landingId' => $landingId,
            'landingType' => $landingType,
            'serverId' => $serverId,
            'serverSkuId' => $serverSkuId,
            'showMoney' => $showMoney,
            'totalMoney' => $totalMoney,
            'payMoney' => $payMoney,
            'payStatus' => Trade::UNPAID,
            'payExpTime' => time() + 3600,
            'settleStatus' => $settleStatus,
            'pf' => $pf,
            'chain' => $chain,
            'promotionGroupId' => $promotionGroupId,
            'attach' => [
                'attach' => '',
                'memberPhone' => $phone,
                'promotionFeedback' => $promotionFeedback,
            ],
        ];

        $record = $this->tradeDao->insertTrade($tradeParams);

        // 触发订单创建事件
        event('TradeCreated', $record);

        // 创建订单后1分钟，如果没有支付，就发短信
        $job_data = ['id' => $record->id];
        Queue::later(60, SmsLanding::class, $job_data);

        return $record;
    }

    // 完成订单
    public function completionTrade(Trade $trade)
    {

        $time = time();
        $trade->startTime = $time;
        $trade->save();

        $landingId = $trade->landingId;
        $serverId = $trade->serverId;
        $serverSkuId = $trade->serverSkuId;


        $landing = Landing::where('id', $landingId)->find();

        $server = ConsultingServer::where('id', $serverId)->find();

        $sku = null;
        if (is_id($serverSkuId)) {
            $sku = ConsultingServerSku::where('id', $serverSkuId)
                                      ->where('consultingServerId', $serverId)
                                      ->find();
        }

        if (!$landing || !$server) {
            // TODO 添加错误日志

            return;
        }

        // 预估律师佣金
        $lawyerMoney = $this->estimateLawyerMoney($trade->payMoney, $trade->settleStatus, $server);

        $trade->lawyerMoney = $lawyerMoney;
        $trade->save();

        // 保存落地页咨询为已支付
        $landing->status = 1;
        $landing->consultingServerId = $serverId;
        $landing->consultingServerSkuId = $serverSkuId;
        $landing->save();

        $this->landingPaid($landing, $server, $sku, $trade);

        // 推广回传
        $this->getPromotionCallbackService()->push($trade);

        // 保存实时播报
        $this->addBroadcast($landing->provinceId);
    }

    // 完成退款，收回服务
    public function completionRefundTrade(Trade $trade)
    {
        $landingId = $trade->landingId;
        $serverId = $trade->serverId;
        $serverSkuId = $trade->serverSkuId;


        $landing = Landing::where('id', $landingId)->find();

        if (!$landing) {
            // TODO 添加错误日志

            return;
        }

        // 标记打官司已退款
        $landing->status = 2;
        $landing->save();

        // 咨询
        $consulting = Consulting::where('landingId', $landing->id)
                                ->find();

        // 服务
        $server = ConsultingServer::where('id', $serverId)->find();

        $serverSku = null;
        if (is_id($serverSkuId)) {
            $serverSku = ConsultingServerSku::where('id', $serverSkuId)
                                            ->where('consultingServerId', $serverId)
                                            ->find();
        }

        if (!$consulting || !$server) {
            // TODO 添加错误日志

            return;
        }

        // 咨询扣除预估律师佣金
        $consulting->lawyerMoney -= $trade->lawyerMoney;
        if ($consulting->lawyerMoney < 0) {
            $consulting->lawyerMoney = 0;
        }
        $consulting->save();

        // 咨询变动事件
        event('ConsultingUpdated', $consulting);

        // 服务回收事件
        event('ConsultingServerRefund', ['consulting' => $consulting, 'server' => $server, 'serverSku' => $serverSku, 'trade' => $trade]);

    }

    public function canceledTrade(Trade $trade)
    {
        return;
    }

    /**
     * 激活落地页
     * @param Landing $landing
     * @param ConsultingServer $server
     * @param ConsultingServerSku|null $serverSku
     * @param Trade $trade
     * @return void
     */
    private function landingPaid(Landing $landing, ConsultingServer $server, ?ConsultingServerSku $serverSku, Trade $trade)
    {

        $serverId = $server->id;
        $serverSkuId = $serverSku ? $serverSku->id : '0';
        $pagePath = $landing->pagePath;
        $landingId = $landing->id;
        $landingType = $landing->landingType;
        $memberId = $landing->memberId;
        $provinceId = $landing->provinceId;
        $cityId = $landing->cityId;
        $categoryId = $landing->categoryId;
        $questionId = $landing->questionId;

        // 渠道链路
        $pf = $landing->pf;
        $chain = $landing->chain;
        $promotionGroupId = $landing->promotionGroupId;

        if ($landing->aryMatch == 1) {
            // 推送给案如云处理

            // 推给案如云
            $lawyerId = '0';
            $initMatchType = Consulting::MATCH_TYPE_ARY;
            $matchType = Consulting::MATCH_TYPE_ARY;
        } else {
            // 熊猫律师接单处理

            $lawyerId = '0';
            // 2023-11-20 周三说改成SVIP没有匹配到，就让普通律师随机匹配
            // $initMatchType = Consulting::MATCH_TYPE_RUSH;
            $initMatchType = Consulting::MATCH_TYPE_RANDOM;
            $matchType = Consulting::MATCH_TYPE_SVIP;
        }

        // 创建咨询
        $consulting = $this->getFreeConsultingService()->addConsulting($server, $serverSku, Consulting::BT_CONSULTING, $memberId, $initMatchType, $matchType, $lawyerId,
            '0', $landingId, $landingType, '0', $categoryId, $provinceId, $cityId, $pf, $chain, $promotionGroupId, $pagePath);

        if (is_id($questionId)) {
            // 提问了

            $question = ConsultingQuestion::where('id', $questionId)->find();

            // 咨询绑定到订单
            $trade->consultingId = $consulting->id;
            $trade->questionId = $questionId;
            $trade->save();

            // 绑定问题
            $consulting->isAsked = '1';
            $consulting->ask = $question->ask;
            $consulting->questionId = $questionId;

            // 激活
            $consulting->status = '1';

            // 付费后，免费咨询变成付费咨询
            if ($consulting->consultingType == 0) {
                $consulting->consultingType = 1;
                $consulting->consultingServerId = $serverId;
                $consulting->consultingServerSkuId = $serverSkuId;
            }

            // 保存预估律师佣金
            $consulting->lawyerMoney = bcadd($consulting->lawyerMoney, $trade->lawyerMoney, 2);

            $consulting->save();

            // 发送首句问题
            $content = [
                'text' => $question->ask,
            ];
            $this->getMessageSendService()->sendMemberMessage($consulting, '0', $memberId, ConsultingMessage::TEXT, $content);

            // 触发 问题绑定 事件
            event('ConsultingQuestionBind', $consulting);

            // 激活服务
            event('ConsultingServerStart', ['consulting' => $consulting, 'server' => $server, 'serverSku' => $serverSku, 'trade' => $trade]);

        } else {
            // 没有提问

            // 咨询绑定到订单
            $trade->consultingId = $consulting->id;
            $trade->save();

            // 激活
            $consulting->status = '1';

            // 付费后，免费咨询变成付费咨询
            if ($consulting->consultingType == 0) {
                $consulting->consultingType = 1;
                $consulting->consultingServerId = $serverId;
                $consulting->consultingServerSkuId = $serverSkuId;
            }

            // 保存预估律师佣金
            $consulting->lawyerMoney = bcadd($consulting->lawyerMoney, $trade->lawyerMoney, 2);

            $consulting->save();

            // 激活服务
            event('ConsultingServerStart', ['consulting' => $consulting, 'server' => $server, 'serverSku' => $serverSku, 'trade' => $trade]);

        }

        if ($matchType == Consulting::MATCH_TYPE_SVIP) {
            // 匹配SVIP
            $this->getConsultingLawyerMatchV3Service()->matchSvip($consulting);
        } else {
            // 推送给案如云
            $this->getARYPushQueueService()->pushLanding($landing->id, true);
        }
    }

    private function getFreeConsultingService(): FreeConsultingService
    {
        return app(FreeConsultingService::class);
    }

    private function getMessageSendService(): MessageSendService
    {
        return app(MessageSendService::class);
    }

    private function getPromotionCallbackService(): \app\common\service\PromotionCallbackService
    {
        return app(\app\common\service\PromotionCallbackService::class);
    }

    private function getARYPushQueueService(): ARYPushQueueService
    {
        return app(ARYPushQueueService::class);
    }

    private function getConsultingLawyerMatchV3Service(): ConsultingLawyerMatchV3Service
    {
        return app(ConsultingLawyerMatchV3Service::class);
    }
}
